package com.platform.jpa.utils;

import org.apache.commons.lang3.reflect.FieldUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectUtil {
    /**
     * 获取指定参数值
     *
     * @param t
     * @param pro getAccountId
     * @param <T>
     * @return
     */
    public static <T> Object getProperty(T t, String pro) {
        Method getPro = null;
        try {
            getPro = t.getClass().getDeclaredMethod(pro, null);
            return getPro.invoke(t, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 获取指定参数值
     *
     * @param t
     * @param pro accountId
     * @param <T>
     * @return
     */
    public static <T> Object getSuperProperty(T t, String pro) {
        Method getPro = null;
        try {
            Field field = t.getClass().getSuperclass().getDeclaredField(pro);
            field.setAccessible(true);
            return field.get(t);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 未指定参数赋值
     *
     * @param t
     * @param pro
     * @param arg
     * @param <T>
     */
    public static <T> void setProperty(T t, String pro, Object arg, Class<?> c) {
        Method getPro = null;
        try {
            getPro = t.getClass().getDeclaredMethod(pro, c);
            getPro.invoke(t, arg);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static <T> Object getFieldValue(T t, String fieldName) {
        try {
            return FieldUtils.readField(t, fieldName, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return -1;
    }

    public static <T, A extends Annotation> A getAnnotation(Class<T> clz, Class<A> annotation) {
        try {
            for (Class<?> acls = clz; acls != null; acls = acls.getSuperclass()) {
                if (acls.isAnnotationPresent(annotation))
                    return acls.getAnnotation(annotation);
                else
                    continue;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> void setFieldValue(T t, String fieldName, Object arg) {
        try {
            if (FieldUtils.getField(t.getClass(), fieldName, true) == null)
                return;
            FieldUtils.writeField(t, fieldName, arg, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static <T> Field getField(Class<T> t, String fieldName) {
        try {
            return FieldUtils.getField(t.getClass(), fieldName, true);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
